/**
 * Copyright (C) 2017 Wasabeef
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var RE = {};
var fontSize = 0;

RE.currentSelection = {
    "startContainer": 0,
    "startOffset": 0,
    "endContainer": 0,
    "endOffset": 0};

RE.editor = document.getElementById('editor');

document.addEventListener("selectionchange", function() { RE.selectionChange(); });

// Initializations
RE.callback = function() {
    alert("re-getText://" + RE.getText());
    window.location.href = "re-callback://" + encodeURI(RE.getHtml());
}

RE.setHtml = function(contents) {
    RE.editor.innerHTML = decodeURIComponent(contents.replace(/\+/g, '%20'));
    RE.setOnImgClick();
    RE.callback();
}

RE.getHtml = function() {
    RE.clearProgressBar();
    return '<p style="font-size:'+RE.editor.style.fontSize+'">'+RE.editor.innerHTML+'</p>';
}

RE.getText = function() {
    return RE.editor.innerText;
}

RE.setBaseTextColor = function(color) {
    RE.editor.style.color  = color;
}

RE.setBaseFontSize = function(size) {
    RE.editor.style.fontSize = size;
}

RE.setPadding = function(left, top, right, bottom) {
  RE.editor.style.paddingLeft = left;
  RE.editor.style.paddingTop = top;
  RE.editor.style.paddingRight = right;
  RE.editor.style.paddingBottom = bottom;
}

RE.setBackgroundColor = function(color) {
    document.body.style.backgroundColor = color;
}

RE.setBackgroundImage = function(image) {
    RE.editor.style.backgroundImage = image;
}

RE.setWidth = function(size) {
    RE.editor.style.minWidth = size;
}

RE.setHeight = function(size) {
    RE.editor.style.height = size;
}

RE.setTextAlign = function(align) {
    RE.editor.style.textAlign = align;
}

RE.setVerticalAlign = function(align) {
    RE.editor.style.verticalAlign = align;
}

RE.setPlaceholder = function(placeholder) {
    RE.editor.setAttribute("placeholder", placeholder);
}

RE.setInputEnabled = function(inputEnabled) {
    RE.editor.contentEditable = String(inputEnabled);
}

RE.undo = function() {
    document.execCommand('undo', false, null);
}

RE.redo = function() {
    document.execCommand('redo', false, null);
}

RE.setBold = function() {
    document.execCommand('bold', false, null);
}

RE.setItalic = function() {
    document.execCommand('italic', false, null);
}

RE.setSubscript = function() {
    document.execCommand('subscript', false, null);
}

RE.setSuperscript = function() {
    document.execCommand('superscript', false, null);
}

RE.setStrikeThrough = function() {
    document.execCommand('strikeThrough', false, null);
}

RE.setUnderline = function() {
    document.execCommand('underline', false, null);
}

RE.setBullets = function() {
    document.execCommand('insertUnorderedList', false, null);
}

RE.setNumbers = function() {
    document.execCommand('insertOrderedList', false, null);
}

RE.setTextColor = function(color) {
    RE.restorerange();
    document.execCommand("styleWithCSS", null, true);
    document.execCommand('foreColor', false, color);
    document.execCommand("styleWithCSS", null, false);
}

RE.setTextBackgroundColor = function(color) {
    RE.restorerange();
    document.execCommand("styleWithCSS", null, true);
    document.execCommand('hiliteColor', false, color);
    document.execCommand("styleWithCSS", null, false);
}

RE.setFontSize = function(fontSize){
    document.execCommand("fontSize", false, fontSize);
}

RE.setFontSize2 = function(size) {
    fontSize = size;
    document.execCommand("fontSize", false, "4");
    RE.preFontSize(false);
}

// 只有光标未选中的情况，执行document.execCommand("fontSize")命令并不是立马插入font标签，
// 而是在有字符输入时插入；如果输入字符前移动过光标，就不再插入font标签
RE.preFontSize = function(selectionChange) {
    if(fontSize > 0) {
        var eleFonts = document.getElementsByTagName("font");
		var isSet = false;
		for(var i=0; i<eleFonts.length; i++) {
			var eleFont = eleFonts[i];
			if(eleFont.getAttribute("size")) {
		    	eleFont.removeAttribute("size");
				eleFont.style.cssText="font-size:"+fontSize+"px;"
				isSet = true;
			}
		}
		if(isSet || selectionChange) {
		    fontSize = 0;
            RE.callback();
		}
	}
}

RE.setHeading = function(heading) {
    document.execCommand('formatBlock', false, '<h'+heading+'>');
}

RE.setIndent = function() {
    document.execCommand('indent', false, null);
}

RE.setOutdent = function() {
    document.execCommand('outdent', false, null);
}

RE.setJustifyLeft = function() {
    document.execCommand('justifyLeft', false, null);
}

RE.setJustifyCenter = function() {
    document.execCommand('justifyCenter', false, null);
}

RE.setJustifyRight = function() {
    document.execCommand('justifyRight', false, null);
}

RE.setBlockquote = function() {
    document.execCommand('formatBlock', false, '<blockquote>');
}

RE.insertImage = function(id, url) {
    var html = '<div id="bar'+id+'" class="progressBar"><div class="progressBarValue" /></div></div><img id="img'+id+'" src="'+url+'"  style="width:100%;opacity:0.4;" /><div><br/></div>'
    //document.execCommand('insertHTML', false, html)
    RE.insertHTML(html);
    RE.setOnImgClick();
}

RE.replaceUrl = function(id, url) {
    document.getElementById("img"+id).src = url;
    RE.callback();
}

RE.setProgress = function(id, progress) {
    document.getElementById("bar"+id).firstElementChild.style.width = (progress) + "%";
    RE.callback();
}

RE.clearProgressBar = function() {
	var eles = document.getElementsByClassName("progressBar");
	for(var i=0; i<eles.length; i++) {
		var barId = eles[i].id;
		var imgId = barId.replace("bar", "img");
		if(!document.getElementById(imgId)) {
			RE.removeProgress(barId.replace("bar", ""));
		}
	}
}

RE.removeProgress = function(id) {
    var bar = document.getElementById("bar"+id);
    bar.parentNode.removeChild(bar);
    //document.getElementById("img"+id).style.opacity=1;
    document.getElementById("img"+id).style.cssText ="width:100%;";
}

RE.removeImg = function(id) {
    var imgEle = document.getElementById(id);
    imgEle.parentNode.removeChild(imgEle);
    RE.clearProgressBar();
    RE.callback();
}

RE.setOnImgClick = function() {
    var imgs = document.getElementsByTagName("img");
    for(var i=0; i<imgs.length; i++) {
        imgs[i].onclick = function() {
            if(this.id == null || this.id=="") {
                this.id = RE.uuid();
            }
            alert("re-onClickImg://" + this.id);
        }
    }
}

RE.uuid = function() {
    var uuid = "";
    for(var i=0; i<4; i++) {
        uuid += (((1+Math.random())*0x10000)|0).toString(16).substring(1);
    }
    return uuid;
}

RE.insertHTML = function(html) {
    RE.restorerange();
    document.execCommand('insertHTML', false, html);
}

RE.mark = function() {
	document.execCommand('insertHTML', false, "“”");
	RE.prepareInsert();
	RE.currentSelection.startOffset = RE.currentSelection.startOffset - 1;
	RE.currentSelection.endOffset = RE.currentSelection.endOffset - 1;
	RE.restorerange();
}

RE.getBIUHState = function() {
	var bold = document.queryCommandValue("bold") == "true" ? 1<<0:0;
	var italic = document.queryCommandValue("italic") == "true" ? 1<<1:0;
	var underline = document.queryCommandValue("underline") == "true" ? 1<<2:0;
	var result = italic | bold | underline;
	var h = RE.getH();
	//alert(h);
	if(h == "h1") {
        result |= (1<<3);

	} else if(h == "h2") {
        result |= (1<<4);

    } else if(h == "h3") {
        result |= (1<<5);

    } else if(h == "h4") {
        result |= (1<<6);
    }

	alert("re-getBIUHState://" + result);
}

RE.getH = function() {
    var fsize = "0px";
    if(fontSize > 0) { // 只设置还未输入字符且未移动光标的情况
        fsize = fontSize + "px";
    } else {
        var selections = document.getSelection();
        var range = selections.getRangeAt(0);
        var ele = range.commonAncestorContainer.parentNode;
        ele = RE.getEleFont(ele);
        fsize = ele.style.fontSize;
    }
    if("25px" == fsize) {
        return "h1";

    } else if("23px" == fsize) {
        return "h2";

    } else if("20px" == fsize) {
        return "h3";

    } else if("18px" == fsize) {
        return "h4";

    } else {
        return "h0";
    }
}

RE.getEleFont = function(ele) {
    if(ele.nodeName == "BODY" || ele.nodeName == "HTML" || ele.id == "editor" || (ele.style.fontSize != null && ele.style.fontSize != "")) {
        return ele;
    }
    return RE.getEleFont(ele.parentNode);
}

RE.insertLink = function(url, title) {
    RE.restorerange();
    var sel = document.getSelection();
    if (sel.toString().length == 0) {
        document.execCommand("insertHTML",false,"<a href='"+url+"'>"+title+"</a>");
    } else if (sel.rangeCount) {
       var el = document.createElement("a");
       el.setAttribute("href", url);
       el.setAttribute("title", title);

       var range = sel.getRangeAt(0).cloneRange();
       range.surroundContents(el);
       sel.removeAllRanges();
       sel.addRange(range);
   }
    RE.callback();
}

RE.setTodo = function(text) {
    var html = '<input type="checkbox" name="'+ text +'" value="'+ text +'"/> &nbsp;';
    document.execCommand('insertHTML', false, html);
}

RE.selectionChange = function() {
    RE.preFontSize(true);
    RE.clearProgressBar();
    RE.backuprange();
    alert("re-selectionChange://" + RE.currentSelection);
}

RE.prepareInsert = function() {
    RE.backuprange();
}

RE.backuprange = function(){
    var selection = window.getSelection();
    if (selection.rangeCount > 0) {
      var range = selection.getRangeAt(0);
      RE.currentSelection = {
          "startContainer": range.startContainer,
          "startOffset": range.startOffset,
          "endContainer": range.endContainer,
          "endOffset": range.endOffset};
    }
}

RE.restorerange = function(){
    var selection = window.getSelection();
    selection.removeAllRanges();
    var range = document.createRange();
    range.setStart(RE.currentSelection.startContainer, RE.currentSelection.startOffset);
    range.setEnd(RE.currentSelection.endContainer, RE.currentSelection.endOffset);
    selection.addRange(range);
}

RE.enabledEditingItems = function(e) {
    var items = [];
    if (document.queryCommandState('bold')) {
        items.push('bold');
    }
    if (document.queryCommandState('italic')) {
        items.push('italic');
    }
    if (document.queryCommandState('subscript')) {
        items.push('subscript');
    }
    if (document.queryCommandState('superscript')) {
        items.push('superscript');
    }
    if (document.queryCommandState('strikeThrough')) {
        items.push('strikeThrough');
    }
    if (document.queryCommandState('underline')) {
        items.push('underline');
    }
    if (document.queryCommandState('insertOrderedList')) {
        items.push('orderedList');
    }
    if (document.queryCommandState('insertUnorderedList')) {
        items.push('unorderedList');
    }
    if (document.queryCommandState('justifyCenter')) {
        items.push('justifyCenter');
    }
    if (document.queryCommandState('justifyFull')) {
        items.push('justifyFull');
    }
    if (document.queryCommandState('justifyLeft')) {
        items.push('justifyLeft');
    }
    if (document.queryCommandState('justifyRight')) {
        items.push('justifyRight');
    }
    if (document.queryCommandState('insertHorizontalRule')) {
        items.push('horizontalRule');
    }
    var formatBlock = document.queryCommandValue('formatBlock');
    if (formatBlock.length > 0) {
        items.push(formatBlock);
    }

    window.location.href = "re-state://" + encodeURI(items.join(','));
}

RE.focus = function() {
    var range = document.createRange();
    range.selectNodeContents(RE.editor);
    range.collapse(false);
    var selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(range);
    RE.editor.focus();
}

RE.blurFocus = function() {
    RE.editor.blur();
}

RE.removeFormat = function() {
    document.execCommand('removeFormat', false, null);
}

// Event Listeners
RE.editor.addEventListener("input", RE.callback);
RE.editor.addEventListener("keyup", function(e) {
    var KEY_LEFT = 37, KEY_RIGHT = 39;
    if (e.which == KEY_LEFT || e.which == KEY_RIGHT) {
        RE.enabledEditingItems(e);
    }
});
RE.editor.addEventListener("click", RE.enabledEditingItems);
